package com.lyang.mall.web.controller;

import com.lyang.mall.api.order.service.OrderService;
import com.lyang.mall.common.entity.ResultObj;
import com.lyang.mall.web.annotation.RedisRateLimit;
import org.apache.log4j.Logger;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicInteger;

@RestController
public class OrderController {
    private static final Logger logger = Logger.getLogger(OrderController.class);

    //限流方法一：Semaphore,只适合单体应用，分布式不适用,它在与限制最大并发数，但不会限制请求数，如果100个请求一个一个过来，都是能访问的
    //private final Semaphore permit = new Semaphore(100, true);
    //限流方法二：AtomicInteger，只适用于单体应用，分布式不适用，它在与限制请求数，注意这个请求数不是绝对的，比如count.incrementAndGet()>100,实际请求数是大于100的，这个是cas本身造成的
    //Semaphore和AtomicInteger配合使用也是一种很好的限流方式，秒杀时限制并发并且限制请求数
    private final AtomicInteger count = new AtomicInteger(1);

    @Resource
    private OrderService orderService;

    @RedisRateLimit(limit = 1000, timeout = 5000)
    @GetMapping("/order/{sid}")
    public Object order(@PathVariable Integer sid){
        ResultObj result = ResultObj.getFail();
        try{
            //permit.acquire();
            if(count.incrementAndGet()>300){
                result.setMsg("请求太多了，就不接待你了。。。");
                return result;
            }
            System.out.println(count);
            result = orderService.createOrder(sid);
            logger.info("下单结果：code="+result.getCode()+",msg="+result.getMsg());
        }catch(Exception e){
            logger.error("下单失败",e);
            result.setMsg(e.toString());
        }finally{
            //permit.release();
        }
        return result;
    }
}
